/*
 Problem Description
唉，小朋友是比较麻烦的。在一个幼儿园里，老师要上一节游戏课，有N个小朋友要玩游戏，做游戏时要用小皮球，
但是幼儿园里只有M个小皮球，而且有些小朋友不喜欢和一些小朋友在一起玩，而只喜欢和另一些小朋友一起玩，
比如傻妞只喜欢和傻瓜，傻根，傻蛋们一起玩，傻根又不喜欢和傻蛋一起玩，傻蛋喜欢和傻子一起玩。
所以老师只好把他们分组，每个组至少有一个小球可以玩，而且每个组内不会有两个小朋友，相互不喜欢。
现在给你这样一个幼儿园里小朋友之间关系的描述，做为老师，是否可以上好这节游戏课。
Input
数据有多个case，每个case先输入两个值N（1<=N<=10）和M(1<=M<=10)，表示有N个小朋友（从0到N-1标号），
和M个小皮球。接着有N行，第i行先输入一个K（0<=K<N），表示第i个小朋友有喜欢一起玩的其他小朋友的个数，
然后后面有K个整数，表示K个小朋友的标号（不重复）。如果A喜欢和B一起玩，则B也喜欢和A一起玩，
这个数据在输入时保证。两个case之间有空行
Output
对于每个case，如果老师可以上好课，输出YES，否则NO。
Sample Input
3 2
2 1 2
2 2 0
2 0 1
Sample Output
YES
 */
package com.yuan.algorithms.practice201504;

import java.util.Scanner;

public class 并查集_幼儿园游戏 {
	static int[] bin;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(sc.hasNext()) {
			int n = sc.nextInt();
			int qiu = sc.nextInt();
			int kh = 0;//控制空行
			bin = new int[n];
			//初始化
            for (int i = 0; i < n; i++) {
                bin[i] = i;
            }
			for (int i = 0; i < n; i++) {
				int k = sc.nextInt();
				for (int j = 0; j < k; j++) {
					int t = sc.nextInt();
					merge(i, t);
				}
			}
			int m = n;//需要的球
			for (int i = 0; i < n; i++) {
                //若值被改变，则说明值所代表小朋友可以相互游戏
				//System.out.println("- "+i+" "+bin[i]);
                if (bin[i] != i) {
                    m--;
                }
            }
			if (kh!=0) {
				System.out.println();
			}
			if (m<=qiu) {
				kh=1;
				System.out.println("YES");
			}else {
				kh=1;
				System.out.println("NO");
			}
		}
	}
	private static void merge(int x, int y) {
        int fx = findx(x);
        int fy = findx(y);
        if (fx != fy) {
            bin[fx] = fy;
        }
    }
    
    private static int findx(int x) {
        int r = x;
        //查找公共根节点
        while(bin[r] != r){
            r = bin[r];
        }
        return r;//返回公共根节点
    }
}
